/*
 *  xyalgorithm/src/integer_split.c
 *
 *  Harry Wei <harryxiyou@gmail.com> (C) 2011
 */
#include <stdio.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#if 0
uint32_t integer_split(uint32_t integer) 
{
	uint32_t i = 0;
	uint32_t tmp = 0;

	if (0 >= integer) {
		g_message("Enter integer!\n");
		return -1;
	} else if (1 == integer) {
		g_print("%d\n", integer);
	}
	uint32_t exchange = integer;
	for (i = exchange; i > 0; i--) {
		if (i == integer) {
			g_print("%d\n", i);
		}
		;
	}
}
#endif

/*
 * re_integer_split_amounts: caculate the amounts of integer division.
 * @para integer: to be divided integer.
 * @para max_addend: the biggest value for division.
 * @return: return the amounts of integer division.
 */
uint32_t re_integer_split_amounts(uint32_t integer, uint32_t max_addend) 
{
#if 0
	if (integer <= 0 || max_addend <= 0) {
		g_message("Enter integer!\n");
		exit(EXIT_FAILURE);
	}
#endif
	if (integer < 1 || max_addend < 1) {
		return 0;
	} 
	if ((1 == integer) || (1 == max_addend)) {
		return 1;
	}
	if (integer < max_addend) {
		return re_integer_split_amounts(integer, integer);
	}
	if (integer == max_addend) {
		return re_integer_split_amounts(integer, max_addend - 1) + 1;
	}
	if (integer > max_addend) {
		return re_integer_split_amounts(integer, max_addend - 1) + 
				re_integer_split_amounts(integer - max_addend, max_addend);
	}
}

/*
 * output: output the stack a2's values.
 * @para a2: the stack a2.
 * @para top2: the index of a2.
 * @return: there is no return value.
 */
static void output(uint32_t *a2, uint32_t top2)
{
	uint32_t i = 0;

	for (i = 0; i < top2 - 1; i++) {
		g_print("%d + ", a2[i]);
	}
	g_print("%d\n", a2[i]);
	return ;
}

/*
 * partion: the operations on integer division.
 * @para top1: the stack a1's amounts.
 * @para top2: the stack a2's amounts.
 * @para a1: the stack a1.
 * @return: there is no return value.
 */
static void partion(uint32_t top1, uint32_t top2, uint32_t *a1) 
{
	uint32_t i = 0;

	if (0 == top1) {
		output(a1, top2);
	} else {
		for (i = top1; i >= 1; i--) {
			if (0 == top2 || i <= a1[top2 - 1]) {
				/* the amount of '1' taken from stack a1 */
				a1[top2] = i;
				/* handle the rest '1' */
				partion(top1 - i, top2 + 1, a1);
			}
		}
	}
	return ;
}

/*
 * re_split: divide the integer into small parts.
 * @para top1: the integer to be devided.
 * @return: -1 is error, 0 is right.
 */
uint32_t re_split(uint32_t top1)
{
	if (0 <= top1) {
		uint32_t top2 = 0;
		uint32_t *a1 = (uint32_t *)g_malloc0(top1 * sizeof(uint32_t));
		if (!a1) {
			g_message("%s -- Allocate Error!\n", __func__);
			return -1;
		}
#if 0
		uint32_t *a2 = (uint32_t *)g_malloc0(top1 * sizeof(uint32_t));
		if (!a2) {
			g_message("%s -- Allocate Error!\n", __func__);
			return -1;
		}
#endif
		memset(a1, 1, top1);
		partion(top1, top2, a1);
	}
	return 0;
}
